安卓Frida Hook之objection

objection

什么是Objection

Objection 是一种用于移动应用安全测试和逆向工程的开源工具,特别是针对 Android 应用程序。它提供了一套强大的功能和命令行工具,帮助安全研究人员、渗透测试人员和开发人员分析和评估移动应用的安全性。

一些 Objection 提供的功能包括:

  1. Runtime Mobile Exploration(RME): 允许用户在设备上动态地探索和分析移动应用程序。可以在运行时修改应用程序的行为、检查内存中的变量等。

  2. SSL Pinning Bypass: 可用于绕过应用程序中实现的 SSL Pinning 机制,从而更轻松地进行网络流量分析。

  3. Frida Scripting: 集成了 Frida 功能,可以编写脚本来 Hook 和修改应用程序的行为。

  4. API 集成: 可以通过 API 接口与 Objection 进行交互,使自动化测试和集成更容易。

  5. 数据解密和加密分析: 可以帮助用户解密应用程序中的数据,并分析加密算法和实现。

    环境配置

1
2
3
mkvirtualenv frida14
pip install objection
pip install frida-tools

objection快速上手

注入命令

1
2
3
4
5
6
objection -g 包名 explore

- help:不知道当前命令的效果是什么,在当前命令前加help比如:help env,回车之后会出现当前命令的解释信息
- 按空格:不知道输入什么就按空格,会有提示出来
- jobs:可以进行多项hook
- 日志:objection的日志文件生成在 C:\Users\Administrator\.objection

启动前就hook

1
objection -g 进程名 explore --startup-command "android hooking watch class 路径.类名"

objection基础api

1
2
memory list modules   -查看内存中加载的库
memory list exports so名称 - 查看库的导出函数
1
2
3
4
5
6
7
8
9
com.zj.wuaipojie on (OnePlus: 11) [usb] # memory list exports libandroidio.so
Save the output by adding `--json exports.json` to this command
Type Name Address
-------- ------------------------------------------ ------------
function async_close_monitor_create 0x7625e87124
function async_close_monitor_destroy 0x7625e87190
function async_close_monitor_signal_blocked_threads 0x7625e870ac
function async_close_monitor_static_init 0x7625e87014
function async_close_monitor_was_signalled 0x7625e87200
1
android hooking list activities -查看内存中加载的activity   android hooking list services -查看内存中加载的services
1
2
3
android intent launch_activity 类名 -启动`activity`或`service`(可以用于一些没有验证的activity,在一些简单的ctf中有时候可以出奇效)

例子:android intent launch_activity com.zj.wuaipojie.ui.ChallengeThird
1
2
关闭ssl校验  android sslpinning disable
关闭root检测  android root disable

objection内存漫游

  1. 内存搜刮类实例
1
2
3
4
5
com.zj.wuaipojie on (google: 13) [usb] # android heap search instances com.zj.wuaipojie.Demo
Class instance enumeration complete for com.zj.wuaipojie.Demo
Hashcode Class toString()
--------- --------------------- -----------------------------
127867717 com.zj.wuaipojie.Demo com.zj.wuaipojie.Demo@79f1b45
  1. 调用实例的方法

无参数

1
2
3
4
5
com.zj.wuaipojie on (google: 13) [usb] # android heap execute 127867717 getPublicInt
Handle 127867717 is to class
com.zj.wuaipojie.Demo
Executing method: getPublicInt()
200

有参数

1
2
3
4
5
6
7
com.zj.wuaipojie on (google: 13) [usb] # android heap evaluate 127867717
(The hashcode at `127867717` will be available as the `clazz` variable.)
console.log(clazz.a("修改后的"));
JavaScript capture complete. Evaluating...
Handle 127867717 is to class
com.zj.wuaipojie.Demo
这是一个修改后的方法
  1. android hooking list classes -列出内存中所有的类(结果比静态分析的更准确)
    这个列出的太多了,一般用不到
  2. android hooking search classes 关键类名 -在内存中所有已加载的类中搜索包含特定关键词的类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
com.zj.wuaipojie on (google: 13) [usb] # android hooking search classes wuaipojie
Note that Java classes are only loaded when they are used, so if the expected class has not been found, it might not have been loaded yet.
com.zj.wuaipojie.Demo
com.zj.wuaipojie.Demo$Animal
com.zj.wuaipojie.Demo$Companion
com.zj.wuaipojie.Demo$InnerClass
com.zj.wuaipojie.Demo$test$1
com.zj.wuaipojie.MainApplication
com.zj.wuaipojie.databinding.ActivityMainBinding
com.zj.wuaipojie.databinding.FragmentHomeBinding
com.zj.wuaipojie.ui.Adapter.ChallengeAdapter
com.zj.wuaipojie.ui.Adapter.ChallengeAdapter$$ExternalSyntheticLambda0
com.zj.wuaipojie.ui.Adapter.ChallengeAdapter$ViewHolder
com.zj.wuaipojie.ui.Challenge
com.zj.wuaipojie.ui.ChallengeSixth
com.zj.wuaipojie.ui.ChallengeSixth$$ExternalSyntheticLambda0
com.zj.wuaipojie.ui.ChallengeSixth$$ExternalSyntheticLambda1
com.zj.wuaipojie.ui.ChallengeSixth$$ExternalSyntheticLambda2
com.zj.wuaipojie.ui.ChallengeSixth$$ExternalSyntheticLambda3
com.zj.wuaipojie.ui.Fragment.ChallengeFragment
com.zj.wuaipojie.ui.Fragment.HomeFragment
com.zj.wuaipojie.ui.MainActivity
com.zj.wuaipojie.ui.MainActivity$$ExternalSyntheticLambda0
com.zj.wuaipojie.ui.MainActivity$handler$1
com.zj.wuaipojie.ui.MainActivity$inlined$sam$i$androidx_navigation_ui_AppBarConfiguration_OnNavigateUpListener$0
com.zj.wuaipojie.ui.MainActivity$onCreate$$inlined$AppBarConfiguration$default$1
com.zj.wuaipojie.util.SPUtils

Found 25 classes
  1. android hooking search methods 关键方法名 -在内存中所有已加载的类的方法中搜索包含特定关键词的方法(一般不建议使用,特别耗时,还可能崩溃)
  1. android hooking list class_methods 类名 -内存漫游类中的所有方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
com.zj.wuaipojie on (google: 13) [usb] # android hooking list class_methods com.zj.wuaipojie.Demo
private final void com.zj.wuaipojie.Demo.complexParameterFunc(java.lang.String,java.util.HashMap<java.lang.Object, java.lang.Object>)
private final void com.zj.wuaipojie.Demo.privateFunc(java.lang.String)
private final void com.zj.wuaipojie.Demo.refl()
private final void com.zj.wuaipojie.Demo.repleaceFunc()
private final void com.zj.wuaipojie.Demo.staticPrivateFunc(java.lang.String)
public final int com.zj.wuaipojie.Demo.getPublicInt()
public final java.lang.String com.zj.wuaipojie.Demo.a(java.lang.String)
public final void com.zj.wuaipojie.Demo.Inner(com.zj.wuaipojie.Demo$Animal,java.lang.String)
public final void com.zj.wuaipojie.Demo.setPublicInt(int)
public final void com.zj.wuaipojie.Demo.test()
public static final java.lang.String com.zj.wuaipojie.Demo.access$getStaticField$cp()

Found 11 method(s)

com.zj.wuaipojie on (google: 13) [usb] # android hooking list class_methods com.zj.wuaipojie.ui.ChallengeSixth
private static final void com.zj.wuaipojie.ui.ChallengeSixth.onCreate$lambda-0(com.zj.wuaipojie.ui.ChallengeSixth,android.view.View)
private static final void com.zj.wuaipojie.ui.ChallengeSixth.onCreate$lambda-1(com.zj.wuaipojie.ui.ChallengeSixth,android.view.View)
private static final void com.zj.wuaipojie.ui.ChallengeSixth.onCreate$lambda-2(com.zj.wuaipojie.ui.ChallengeSixth,android.view.View)
private static final void com.zj.wuaipojie.ui.ChallengeSixth.onCreate$lambda-3(com.zj.wuaipojie.ui.ChallengeSixth,android.view.View)
protected void com.zj.wuaipojie.ui.ChallengeSixth.onCreate(android.os.Bundle)
public final java.lang.String com.zj.wuaipojie.ui.ChallengeSixth.hexToString(java.lang.String)
public final java.lang.String com.zj.wuaipojie.ui.ChallengeSixth.unicodeToString(java.lang.String)
public final void com.zj.wuaipojie.ui.ChallengeSixth.toastPrint(java.lang.String)
public static void com.zj.wuaipojie.ui.ChallengeSixth.$r8$lambda$1lrkrgiCEFWXZDHzLRibYURG1h8(com.zj.wuaipojie.ui.ChallengeSixth,android.view.View)
public static void com.zj.wuaipojie.ui.ChallengeSixth.$r8$lambda$IUqwMqbTKaOGiTaeOmvy_GjNBso(com.zj.wuaipojie.ui.ChallengeSixth,android.view.View)
public static void com.zj.wuaipojie.ui.ChallengeSixth.$r8$lambda$Kc_cRYZjjhjsTl6GYNHbgD-i6sE(com.zj.wuaipojie.ui.ChallengeSixth,android.view.View)
public static void com.zj.wuaipojie.ui.ChallengeSixth.$r8$lambda$PDKm2AfziZQo6Lv1HEFkJWkUsoE(com.zj.wuaipojie.ui.ChallengeSixth,android.view.View)

Found 12 method(s)

objectionHook

  1. hook类的所有方法

    好像没什么效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
com.zj.wuaipojie on (google: 13) [usb] # android hooking watch class com.zj.wuaipojie.Demo --dump-backtrace --dump-args
--dump-return
(agent) Hooking com.zj.wuaipojie.Demo.access$getStaticField$cp()
(agent) Hooking com.zj.wuaipojie.Demo.complexParameterFunc(java.lang.String, java.util.HashMap)
(agent) Hooking com.zj.wuaipojie.Demo.privateFunc(java.lang.String)
(agent) Hooking com.zj.wuaipojie.Demo.refl()
(agent) Hooking com.zj.wuaipojie.Demo.repleaceFunc()
(agent) Hooking com.zj.wuaipojie.Demo.staticPrivateFunc(java.lang.String)
(agent) Hooking com.zj.wuaipojie.Demo.Inner(com.zj.wuaipojie.Demo$Animal, java.lang.String)
(agent) Hooking com.zj.wuaipojie.Demo.a(java.lang.String)
(agent) Hooking com.zj.wuaipojie.Demo.getPublicInt()
(agent) Hooking com.zj.wuaipojie.Demo.setPublicInt(int)
(agent) Hooking com.zj.wuaipojie.Demo.test()
(agent) Registering job 919624. Type: watch-class for: com.zj.wuaipojie.Demo
  1. hook方法的参数、返回值和调用栈
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
com.zj.wuaipojie on (google: 13) [usb] # android hooking watch class_method com.zj.wuaipojie.Demo.a --dump-args --dump-
return --dump-backtrace
(agent) Attempting to watch class com.zj.wuaipojie.Demo and method a.
(agent) Hooking com.zj.wuaipojie.Demo.a(java.lang.String)
(agent) Registering job 276091. Type: watch-method for: com.zj.wuaipojie.Demo.a
com.zj.wuaipojie on (google: 13) [usb] # (agent) [276091] Called com.zj.wuaipojie.Demo.a(java.lang.String)
(agent) [276091] Backtrace:
com.zj.wuaipojie.Demo.a(Native Method)
com.zj.wuaipojie.Demo.test(Demo.kt:19)
com.zj.wuaipojie.ui.ChallengeSixth.onCreate(ChallengeSixth.kt:36)
android.app.Activity.performCreate(Activity.java:8342)
android.app.Activity.performCreate(Activity.java:8321)
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1417)
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3625)
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3781)
android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:138)
android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:2306)
android.os.Handler.dispatchMessage(Handler.java:106)
android.os.Looper.loopOnce(Looper.java:201)
android.os.Looper.loop(Looper.java:288)
android.app.ActivityThread.main(ActivityThread.java:7918)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

(agent) [276091] Arguments com.zj.wuaipojie.Demo.a(普通)
(agent) [276091] Return Value: 这是一个普通方法

其他例子:

1
android hooking watch class_method com.zj.wuaipojie.Demo.privateFunc --dump-args --dump-return --dump-backtrace
  1. hook 类的构造方法
1
android hooking watch class_method com.zj.wuaipojie.Demo.$init --dump-args --dump-backtrace
  1. hook 方法的所有重载
1
android hooking watch class_method com.zj.wuaipojie.Demo.repleaceFunc

调用repleaceFunc的时候会显示

1
(agent) [107162] Called com.zj.wuaipojie.Demo.repleaceFunc()

trace实战java控制流混淆

项目地址:
BlackObfuscator

示例1:

示例2:

对抗方法

  1. ZenTracer
    项目地址

缺点:无法打印调用栈,无法hook构造函数

支持frida的版本firda==14.2.18,可以通过frida-tools==9.2.4来安装

1
2
pip install frida-tools==9.2.4
pip install PyQt5
1
2
3
4
5
6
7
8
//使用说明
1.运行server端
2.点击action
3.点击Match Regex设置过滤标签
4.输入包名(或者方法名等可以过滤的标签),点击add
5.点击action的start
6.点击应用触发相应的逻辑
7.可左上角fils-Export JSON来导出日志分析

具体使用实例

  1. 先启动frida-server
1
OnePlus3:/data/local/tmp # ./frida-server-14.2.18-android-arm64
  1. 手机打开要分析的app
  1. 电脑端设置过滤


  1. 之后点击start,有下面的日志说明hook成功


清空软件的log,点击app的功能(这里是flag验证)

就可以看到使用的加密算法,加密后的返回值,最终retval是

tips:可以导出json复制查看

    1. r0tracer
      项目地址

兼容最新版本frida,16.2.1

使用方法

  1. 修改r0tracer.js文件最底部处的代码,开启某一个Hook模式。

比如hook有wuaipojie2023_1关键字的所有类

1
hook("wuaipojie2023_1");
  1. 推荐使用Frida14版本,并且将日志使用-o参数进行输出保存
1
2
frida -U -f com.zj.wuaipojie2023_1 -l r0tracer.js  --no-pause
frida -U -f com.zj.wuaipojie2023_1 -l r0tracer.js --no-pause -o saveLog.txt

“-f”为Spawn模式,去掉”-f”为Attach模式

注意: hook不到类的话,还需要再app点击相应的功能,之后执行%reload一下,看看是否hook所有类

最开始也是只有4个类

1
2
3
4
5
6
7
Search Class Completed!
On Total Tracing :4 classes :
com.zj.wuaipojie2023_1.MainActivity
com.zj.wuaipojie2023_1.MD5Utils
com.zj.wuaipojie2023_1.Base64Utils
com.zj.wuaipojie2023_1.MainActivity$$ExternalSyntheticLambda0
Start Tracing ...

后面app点击相应的功能,之后执行%reload一下才hook7个

1
2
3
4
5
6
7
8
9
10
Search Class Completed!
On Total Tracing :7 classes :
com.zj.wuaipojie2023_1.B
com.zj.wuaipojie2023_1.MainActivity
com.zj.wuaipojie2023_1.C
com.zj.wuaipojie2023_1.MD5Utils
com.zj.wuaipojie2023_1.Base64Utils
com.zj.wuaipojie2023_1.MainActivity$$ExternalSyntheticLambda0
com.zj.wuaipojie2023_1.A
Start Tracing ...
  1. Frida版本=<12时,要加上–runtime=v8选项
打赏专区